package com.world.cat.app;

import com.world.cat.service.sys.MenuService;
import com.world.common.pojo.tree.BaseTreeNode;
import com.world.common.util.SessionUtil;
import com.world.common.util.SysUtil;
import com.world.common.util.WebUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.util.StopWatch;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.UUID;

/**
 * Created by gang on 2017/1/24.
 */
public class AppInterceptor extends HandlerInterceptorAdapter implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(AppInterceptor.class);
    private NamedThreadLocal<StopWatch> stopWatchThreadLocal = new NamedThreadLocal<>("ConsumeTime-StopWatch");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (SysUtil.isDevMode()) {
            request.setAttribute("dev", true);
        }
        request.setAttribute("basePath", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/");
        request.setAttribute("contextPath", request.getContextPath());
        if (SysUtil.isNotEmpty(SessionUtil.getUserName())) {
            if (!WebUtil.isAjaxRequest(request)) {
                logger.info(request.getServletPath());
                String url = request.getServletPath();
                String activeUrl = AppConstant.defaultRelatedMenuMap.get(url);
                if (SysUtil.isNotEmpty(url)&&url.startsWith("/auto")) {
                    String entityStr = request.getParameter("o");
                    activeUrl = AppConstant.AUTO_HOME + "?o=" + entityStr;
                }
                if (activeUrl != null && MenuService.urlMenuMap.containsKey(activeUrl)) {
                    BaseTreeNode treeNode = MenuService.getAceResourceTree(SessionUtil.getUserName(), activeUrl);
                    request.setAttribute("rootNode", treeNode);
                    request.setAttribute("nodeNav", MenuService.getNodeNav(activeUrl));
                }
            }
        }
        //todo 可以在这里统一检查用户是否登录
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        SessionUtil.clear();
    }

    private void logRequestParams(HttpServletRequest request, UUID uuid) {
        try {
            StringBuilder sb = new StringBuilder();
            Enumeration<String> pNames = request.getParameterNames();
            while (pNames.hasMoreElements()) {
                String pName = pNames.nextElement();
                String pValues[] = request.getParameterValues(pName);
                StringBuilder result = new StringBuilder(pName);
                result.append('=');
                for (int i = 0; i < pValues.length; i++) {
                    if (i > 0)
                        result.append(", ");
                    result.append(pValues[i]);
                }
                sb.append(result).append(", ");
            }
            logger.info("标识ID: {}. 请求URL: {}", uuid.toString(), request.getRequestURL());
            logger.info("标识ID: {}. 请求参数: {}", uuid.toString(), sb.substring(0, sb.length() > 1 ? sb.length() - 2 : sb.length()));
            logBrowserInfo(request, uuid);
        } catch (Exception e) {
            logger.warn("Log请求参数时出错.", e);
        }
    }

    private void logBrowserInfo(HttpServletRequest request, UUID uuid) {
        try {
            StringBuilder sb = new StringBuilder();
            sb.append("IP地址=").append(request.getRemoteAddr()).append(":").append(request.getServerPort()).append(", ")
                    .append("客户端用户名=").append(request.getRemoteHost()).append(", ");
            Enumeration<String> hNames = request.getHeaderNames();
            while (hNames.hasMoreElements()) {
                String hName = hNames.nextElement();
                String hValue = request.getHeader(hName);
                sb.append(hName).append('=').append(hValue).append(", ");
            }
            logger.info("标识ID: {}. 请求user浏览器详细信息:[{}]", uuid.toString(), sb.substring(0, sb.length() > 1 ? sb.length() - 2 : sb.length()));
        } catch (Exception e) {
            logger.warn("Log请求参数时出错.", e);
        }
    }
}